package com.ddwl.wallet.service;

import com.ddwl.common.constant.*;
import com.ddwl.common.constant.DistConstant.WalletFlowType;
import com.ddwl.common.exception.ParamException;
import com.ddwl.wallet.dao.DistOrderInfoDao;
import com.ddwl.wallet.dao.OrderDao;
import com.ddwl.wallet.dao.SysOrderRefundDao;
import com.ddwl.wallet.dao.model.DistOrder;
import com.ddwl.wallet.dao.model.DistOrderInfo;
import com.ddwl.wallet.dao.model.SysOrderRefund;
import com.ddwl.wallet.service.dto.UserWalletChangeDto;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;

/**
 * 类OrderPayOffService.java的实现描述：分销订单结算
 *
 * @author zach
 * @Date :2020-07-24 15:51.
 */
@Service
public class OrderPayOffService {

    @Resource
    private OrderDao orderDao;
    @Resource
    private UserWalletService userWalletService;
    @Resource
    private DistOrderInfoDao distOrderInfoDao;
    @Resource
    private SysOrderRefundDao sysOrderRefundDao;
    @Resource
    private RabbitTemplate rabbitTemplate;


    /**
     * 结算店铺佣金
     */
    @Transactional(rollbackFor = Exception.class)
    public void payOffShopCommission(String orderId){
        DistOrderInfo distOrderInfo = distOrderInfoDao.queryDistOrderByOrderId(orderId);
        ParamException.isNull(distOrderInfo,"结算店铺订单异常，店铺订单不存在");
        if(!StringUtils.hasText(distOrderInfo.getShopId())&&distOrderInfo.getPlatformTag()!=1){
            return;
        }
        DistOrder distOrder = orderDao.queryDistOrder(orderId,null,DistTypeEnum.SHOP.getType());
        ParamException.isNull(distOrder,"店铺分销单不存在无法完成结算");
        ParamException.isTrue(DistConstant.DistOrderStatus.CLOSE.getCode().equals(distOrder.getOrderStatus()),"当前订单状态不是收货状态，无法完成结算");
        UserWalletChangeDto distAmount = UserWalletChangeDto.buildUserWalletChangeDto(distOrder.getOrderId(),distOrder.getDistUserId(),WalletFlowType.SHOP,distOrder.getDistAmount());
        userWalletService.userWalletChange(distAmount);
        DistOrder update = new DistOrder();
        update.setId(distOrder.getId());
        update.setClearingTime(Instant.now());
        update.setOrderStatus(DistConstant.DistOrderStatus.CLOSE.getCode());
        orderDao.updateByPrimaryKeySelective(update);
        DistOrderInfo orderInfo = new DistOrderInfo();
        orderInfo.setId(distOrderInfo.getId());
        orderInfo.setShopClearingTime(Instant.now());
        orderInfo.setShopSettlementStatus(BaseEnum.ApplyEnum.SUCCEED.getCode());
        distOrderInfoDao.updateByPrimaryKeySelective(orderInfo);
    }

    /**
     * 公益基金收入
     */
    private void charityFundIncome(String recordId,BigDecimal amount){
        UserWalletChangeDto distAmount = UserWalletChangeDto.buildUserWalletChangeDto(recordId, UserEnum.AccountEnum.CHARITY_ACCOUNT.getId(),WalletFlowType.CHARITY_FUND, amount);
        userWalletService.userWalletChange(distAmount);
    }

    /**
     * 结算分销佣金
     * @param orderId
     */
    @Transactional(rollbackFor = Exception.class)
    public void payOffDistCommission(String orderId){
        DistOrderInfo distOrderInfo = distOrderInfoDao.queryDistOrderByOrderId(orderId);
        ParamException.isNull(distOrderInfo,"结算佣金订单异常，分销订单不存在");
        List<DistOrder> distOrders = orderDao.queryPayOffDistOrder(orderId);
        distOrders.stream().forEach(distOrder -> {
            UserWalletChangeDto distAmount = UserWalletChangeDto.buildUserWalletChangeDto(distOrder.getOrderId(),distOrder.getDistUserId(),WalletFlowType.JS,distOrder.getDistAmount());
            userWalletService.userWalletChange(distAmount);
            DistOrder update = new DistOrder();
            update.setId(distOrder.getId());
            update.setClearingTime(Instant.now());
            update.setOrderStatus(DistConstant.DistOrderStatus.CLOSE.getCode());
            orderDao.updateByPrimaryKeySelective(update);
        });
        List<SysOrderRefund> refunds = sysOrderRefundDao.queryOrderRefundOngoing(orderId);
        List<DistOrder> noPayOffDistOrders  =  orderDao.queryNoPayOffDistOrder(orderId);
        //如果没有退款中的售后单则订单结算完成，如果有结算中的可能需要二次结算
        if(CollectionUtils.isEmpty(refunds)&&CollectionUtils.isEmpty(noPayOffDistOrders)){
            distOrderInfo.setClearingTime(Instant.now());
            distOrderInfo.setSettlementStatus(BaseEnum.ApplyEnum.SUCCEED.getCode());
            distOrderInfoDao.updateByPrimaryKeySelective(distOrderInfo);
        }
    }


    /**
     * 结算分销指定时间内收货的订单
     */
    public void orderPayOffDist(Instant startTime,Instant endTime){
        List<DistOrderInfo>  distOrders = distOrderInfoDao.queryGtTimeSettleDistOrder(startTime,endTime);
        distOrders.forEach(distOrderInfo -> {
            rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_DIST_ORDER_SETTLEMENT_AMOUNT_QUEUE,distOrderInfo.getOrderId());
        });
    }

    /**
     * 结算店铺指定时间之内收货分销订单
     */
    public void orderPayOffShop(Instant startTime,Instant endTime){
        List<DistOrderInfo>  distOrders = distOrderInfoDao.queryGtTimeSettleShopOrder(startTime,endTime);
        distOrders.forEach(distOrderInfo -> {
            rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_SHOP_ORDER_SETTLEMENT_AMOUNT_QUEUE,distOrderInfo.getOrderId());
        });
    }


    /**
     * 实时结算开门店佣金
     */
    @Transactional(rollbackFor = Exception.class)
    public void orderPayOffShopApprove() {
        List<DistOrderInfo>  distOrders = distOrderInfoDao.queryGtTimeShopSettleDistOrder(null,null);
        distOrders.forEach(distOrderInfo -> {
            rabbitTemplate.convertAndSend(RabbitMqConstants.DIST_DIST_ORDER_SETTLEMENT_AMOUNT_QUEUE,distOrderInfo.getOrderId());
        });
    }

}
